export class RefQueue{
    constructor(capacity){
        this.container=new Map();
        this.zeroRefContainer=new Map();
        this.zeroArray=[];
        this.capacity=capacity||10;
        this.length=0;
        
    }
    get(key){
        let element=this.container.get(key);
        let isFromZero=false;
        if(!element){
            element=this.zeroRefContainer.get(key);
            isFromZero=true;
        }

        if(!element)return null;
        ++element.refCount;
        if(isFromZero){
            this._transToContainer(key,element);
        }
        return element;
    }

    set(key,element){
        if(element.refCount==undefined){
            element.refCount=0;
            ++this.length;
        }
        element.key=key;
        this.zeroRefContainer.set(key,element);
    }

    release(key,element){
        if(!element){
            element=this.container.get(key);
        }

        if(!element)return;

        --element.refCount;

        if(element.refCount<=0){
            element.refCount=0;
            this._transToZero(key,element);
        }

        while(this.zeroArray.length>0&&this.length>this.capacity){
            let zeroElement=this.zeroArray.shift();
            this.zeroRefContainer.delete(zeroElement.key);
            this.destroyElement(zeroElement);
            --this.length;
        }
    }

    clear(){
        for(let [,value] of this.container){
            this.destroyElement(value);
        }
        this.container.clear();

        for(let [,value] of this.zeroRefContainer){
            this.destroyElement(value);
        }
        this.zeroRefContainer.clear();

        this.zeroArray.length=0;
        this.length=0;
    }

    _transToZero(key,element){
        this.container.delete(key);
        this.zeroRefContainer.set(key,element);
        this.zeroArray.push(element);
    }

    _transToContainer(key,element){
        let index=this.zeroArray.lastIndexOf(element);
        if(index==-1)return;
        this.zeroRefContainer.delete(key);
        this.zeroArray.splice(index,1);
        this.container.set(key,element);
    }

    destroyElement(element){}
}